(function() {
  var $shortcutIcon = $('#shortcut-icon');
  var $iconChangeWrapper = $('#icon-change-wrapper');
  var $shortcutIconWrapper = $('#shortcut-icon-wrapper');
  var $iconSelectionArea = $('#icon-selection-area');
  
  var si = window.ShortcutIcon = {
    defaultIcons: ['default', 'alerts', 'android', 'blogger', 'buzz',
      'chrome_web_store', 'code', 'docs', 'ebooks', 'googlemail', 'maps_api',
      'mobile', 'music', 'phone', 'picasa', 'picnik', 'rss', 'toolbar',
      'websearchfeatures', 'youtube'],
    
    setup: function() {
      $iconSelectionArea.on('click', function(event) {
        var target = event.target;
        if (target.tagName == 'IMG') {
          si.selectIcon(target);
          event.stopPropagation();
        }
      });
      
      $shortcutIconWrapper.on('click', si.showIconChangeWrapper);
      $('#icon-selection-cancel-btn').on('click', si.hideIconChangeWrapper);
      
      $('#icon-selection-btn').on('click', function() {
        var $selectedIcon = $('.icon-selected', $iconSelectionArea);
        var iconId = $selectedIcon.attr('data-icon-id');
        var iconData = {
          id: iconId,
          src: $selectedIcon.attr('src'),
          file: $selectedIcon.attr('data-icon-file') || iconId,
          index: $selectedIcon.attr('data-icon-index') || 0
        };
        si.setIconData(iconData);
        si.hideIconChangeWrapper();
      });

      $('#more-icon-selection-link').on('click', function() {
        var icon = Fs.selectIcon();
        if (icon) {
          var iconFile = icon.file;
          var iconIndex = icon.index;
          var iconId = IconStorage.isExist(iconFile, iconIndex);
          var img = $('[data-icon-id="' + iconId + '"]', $iconSelectionArea);
          if (!iconId) {
            iconId = si.generateIconId();
            icon.id = iconId;
            IconStorage.addIcon(iconId, icon.file, icon.index);
            img = si.addIcon(icon);
          }
          si.selectIcon(img);
        }
      });

      // Set default icon.
      var defaultIcon = Fs.getDefaultIconData();
      $('[data-icon-id="default"]', $iconSelectionArea).attr('src', defaultIcon);

      si.addCustomIcons();
    },

    init: function() {
      var src = Fs.getDefaultIconData();
      $shortcutIcon.attr('src', src)
        .attr('data-icon-id', 'default').attr('data-icon-file', 'default')
        .attr('data-icon-index', 0);
    },

    generateIconId: function() {
      return 'icon-' + new Date().getTime();
    },

    isExist: function(iconId) {
      if (si.defaultIcons.indexOf(iconId) >= 0) {
        return true;
      }
      return IconStorage.getIcon(iconId);
    },
    
    addCustomIcons: function() {
      var icons = IconStorage.getIcons();
      var iconId;
      var icon;
      var iconData;
      for (iconId in icons) {
        icon = icons[iconId];
        iconData = Fs.selectIcon(icon.file, icon.index);
        if (iconData) {
          si.addIcon({
            id: iconId,
            file: icon.file,
            index: icon.index,
            base64Data: iconData.base64Data
          });
        } else {
          IconStorage.deleteIcon(iconId);
        }
      }
    },
    
    /**
     * Add an icon to icon selection list.
     * @param {Object} iconData
     *   required keys: id, base64Data, file, index
     */
    addIcon: function(iconData) {
      var iconId = iconData.id;
      var img = document.createElement('img');
      $(img).attr('data-icon-id', iconId).attr('data-icon-file', iconData.file)
        .attr('data-icon-index', iconData.index)
        .attr('src', iconData.base64Data);
      $iconSelectionArea.prepend(img);
      return img;
    },
    
    getIconData: function() {
      var id = $shortcutIcon.attr('data-icon-id');
      var src = $shortcutIcon.attr('src');
      var iconFile = $shortcutIcon.attr('data-icon-file') || id;
      var iconIndex = parseInt($shortcutIcon.attr('data-icon-index')) || 0;
      return {
        id: id,
        src: src,
        file: iconFile,
        index: iconIndex
      };
    },
    
    setIconData: function(icon) {
      $shortcutIcon.attr('data-icon-id', icon.id);
      $shortcutIcon.attr('src', icon.src);
      $shortcutIcon.attr('data-icon-file', icon.file);
      $shortcutIcon.attr('data-icon-index', icon.index);
    },

    showIconChangeWrapper: function() {
      $.setDialogPosition($iconChangeWrapper.get());
      $iconChangeWrapper.show();
      Manager.showOverlay();
      si.selectInvertIcon();
    },

    hideIconChangeWrapper: function() {
      $iconChangeWrapper.hide();
      Manager.hideOverlay();
    },

    selectIcon: function(icon) {
      $('.icon-selected', $iconSelectionArea).removeClass('icon-selected');
      $(icon).addClass('icon-selected');
    },

    selectInvertIcon: function() {
      var iconId = $shortcutIcon.attr('data-icon-id');
      var $selectedIcon = $('img[data-icon-id="' + iconId + '"]',
        $iconSelectionArea);
      si.selectIcon($selectedIcon);
      $iconSelectionArea.prepend($selectedIcon.get());
    },

    applyIcon: function(shortcut) {
      var iconId = shortcut.iconId;
      si.setIconData({
        id: iconId,
        src: shortcut.icon,
        file: shortcut.iconFile,
        index: shortcut.iconIndex
      });
    }
  };
})();